﻿using System;
using System.Collections.Generic;
using System.Windows.Controls;
using Dsl.Ped.Controls.ProjectiveControl;
using NUnit.Framework;

namespace DSLPedControlsTest.ProjectiveControl
{
    [TestFixture]
    public class ProjectionContainerTest
    {
        #if DEBUG
        
        private Dictionary<string, List<TransitionInfo>> transitions;

        private List<ProjectionControl> projections;

        [SetUp]
        public void SetUp()
        {
            if (!UriParser.IsKnownScheme("pack"))
                new System.Windows.Application();

            transitions = new Dictionary<string, List<TransitionInfo>>();

            transitions.Add("MouseDown",
                new List<TransitionInfo>{new TransitionInfo {FromProjection = "AAA", ToProjection = "BBB", EventName = "MouseDown"}});
            transitions.Add("MouseMove",
                new List<TransitionInfo>{
                    new TransitionInfo() {FromProjection = "AAA", ToProjection = "CCC", EventName = "MouseMove" },
                    new TransitionInfo() {FromProjection = "EEE", ToProjection = "DDD", EventName = "MouseMove" }});

            projections = new List<ProjectionControl>()
                                  {
                                      new ProjectionControl() {Name = "CCC"},
                                      new ProjectionControl() {Name = "DDD"}
                                  };
        }

        #region GetProjectionToTransitName

        [Test, RequiresSTA]
        public void GetProjectionToTransitNameTest1()
        {
            var projectionContainer = new ProjectionContainerControl();

            var proj = projectionContainer.GetProjectionToTransitName(transitions, "AAA", "", "MouseDown");
            Assert.AreEqual("BBB", proj);

            proj = projectionContainer.GetProjectionToTransitName(transitions, "AAA", "", "MouseMove");
            Assert.AreEqual("CCC", proj);
        }

        [Test, RequiresSTA]
        public void GetProjectionToTransitNameTest2()
        {
            var projectionContainer = new ProjectionContainerControl();

            var proj = projectionContainer.GetProjectionToTransitName(null, "AAA", "", "MouseDown");
            Assert.AreEqual(proj, string.Empty);
        }

        [Test, RequiresSTA]
        public void GetProjectionToTransitNameTest3()
        {
            var projectionContainer = new ProjectionContainerControl();

            var proj = projectionContainer.GetProjectionToTransitName(transitions, null, "", "MouseDown");
            Assert.AreEqual(proj, string.Empty);
        }

        [Test, RequiresSTA]
        public void GetProjectionToTransitNameTest4()
        {
            var projectionContainer = new ProjectionContainerControl();

            var proj = projectionContainer.GetProjectionToTransitName(transitions, "AAA", "", null);
            Assert.AreEqual(proj, string.Empty);
        }

        [Test, RequiresSTA]
        public void GetProjectionToTransitNameTest5()
        {
            var projectionContainer = new ProjectionContainerControl();

            var proj = projectionContainer.GetProjectionToTransitName(transitions, null, "", null);
            Assert.AreEqual(proj, string.Empty);
        }

        [Test, RequiresSTA]
        public void GetProjectionToTransitNameTest6()
        {
            var projectionContainer = new ProjectionContainerControl();

            var proj = projectionContainer.GetProjectionToTransitName(null, null, "", null);
            Assert.AreEqual(proj, string.Empty);
        }

        #endregion GetProjectionToTransitName

        #region GetProjectionByName

        [Test, RequiresSTA]
        public void GetProjectionByNameTest1()
        {
            var projectionContainer = new ProjectionContainerControl();

            var projection = projectionContainer.GetProjectionByName(projections, "AAA");
            Assert.AreEqual(null, projection);
        }

        [Test, RequiresSTA]
        public void GetProjectionByNameTest2()
        {
            var projectionContainer = new ProjectionContainerControl();

            var projection = projectionContainer.GetProjectionByName(projections, "CCC");
            Assert.AreEqual(projection.Name, "CCC");

            projection = projectionContainer.GetProjectionByName(projections, "DDD");
            Assert.AreEqual(projection.Name, "DDD");
        }

        [Test, RequiresSTA]
        public void GetProjectionByNameTest3()
        {
            var projectionContainer = new ProjectionContainerControl();

            var projection = projectionContainer.GetProjectionByName(projections, null);
            Assert.AreEqual(null, projection);
        }

        [Test, RequiresSTA]
        public void GetProjectionByNameTest4()
        {
            var projectionContainer = new ProjectionContainerControl();

            var projection = projectionContainer.GetProjectionByName(null, "AAA");
            Assert.AreEqual(null, projection);
        }

        #endregion GetProjectionByName

        #region OnEventDrivenProjection

        [Test, RequiresSTA]
        public void OnEventDrivenProjectionTest1()
        {
            var projectionContainer2 =
                new ProjectionContainerControl(new List<TransitionControl>
                                {
                                    new TransitionControl()
                                        {FromProjection = "AAA", ToProjection = "BBB", Event = "MouseDown"}
                                });
            projectionContainer2.Items.Add(new ProjectionControl() { Name = "AAA" });
            projectionContainer2.Items.Add(new ProjectionControl() { Name = "BBB" });
            projectionContainer2.SelectedItem = projectionContainer2.Items[0];

            projectionContainer2.OnEventDrivenProjection(projectionContainer2, "", "MouseDown");

            Assert.AreEqual(projectionContainer2.SelectedItem, projectionContainer2.Items[1]);
        }

        [Test, RequiresSTA]
        public void OnEventDrivenProjectionTest2()
        {
            var projectionContainer2 =
                new ProjectionContainerControl(new List<TransitionControl>
                    {
                        new TransitionControl()
                            {FromProjection = "AAA", ToProjection = "BBB", Event = "MouseDown"}
                    });

            projectionContainer2.Items.Add(new ProjectionControl() { Name = "AAA" });
            projectionContainer2.Items.Add(new ProjectionControl() { Name = "BBB" });
            projectionContainer2.SelectedItem = projectionContainer2.Items[0];
            projectionContainer2.OnEventDrivenProjection(null, "", "MouseDown");

            Assert.AreEqual(projectionContainer2.SelectedItem, projectionContainer2.Items[0]);
        }

        [Test, RequiresSTA]
        public void OnEventDrivenProjectionTest3()
        {
            var projectionContainer2 = new ProjectionContainerControl();
            projectionContainer2.Items.Add(new ProjectionControl() { Name = "AAA" });
            projectionContainer2.Items.Add(new ProjectionControl() { Name = "BBB" });
            projectionContainer2.SelectedItem = projectionContainer2.Items[0];
            projectionContainer2.Transitions.Add(new TransitionControl() { FromProjection = "AAA", ToProjection = "BBB", Event = "MouseDown" });

            projectionContainer2.OnEventDrivenProjection(projectionContainer2, "", null);

            Assert.AreEqual(projectionContainer2.SelectedItem, projectionContainer2.Items[0]);
        }

        #endregion OnEventDrivenProjection

        #region OnItemsChanged

        [Test, RequiresSTA]
        public void OnItemsChangedTest1()
        {
            var projectionContainer2 = new ProjectionContainerControl();
            projectionContainer2.Items.Add(new ProjectionControl() { Name = "AAA" });
            Assert.AreEqual(1, projectionContainer2.Projections.Count);
            Assert.AreEqual("AAA", projectionContainer2.Projections[0].Name);

            projectionContainer2.Items.Add(new ProjectionControl() { Name = "BBB" });
            Assert.AreEqual(2, projectionContainer2.Projections.Count);
            Assert.AreEqual("AAA", projectionContainer2.Projections[0].Name);
            Assert.AreEqual("BBB", projectionContainer2.Projections[1].Name);
        }


        [Test, RequiresSTA]
        public void OnItemsChangedTest2()
        {
            var projectionContainer2 = new ProjectionContainerControl();
            projectionContainer2.Items.Add(new TabItem() { Name = "AAA" });
            Assert.AreEqual(0, projectionContainer2.Projections.Count);

            projectionContainer2.Items.Add(new ProjectionControl() { Name = "BBB" });
            Assert.AreEqual(1, projectionContainer2.Projections.Count);
            Assert.AreEqual("BBB", projectionContainer2.Projections[0].Name);
            Assert.AreEqual(1, projectionContainer2.Items.Count);
        }

        #endregion OnItemsChanged

        #region RemoveItems

        [Test, RequiresSTA]
        public void RemoveItemsTest1()
        {
            var projectionContainer2 = new ProjectionContainerControl();

            var projection1 = new ProjectionControl() {Name = "AAA"};
            projectionContainer2.Items.Add(projection1);

            var projection2 = new ProjectionControl() {Name = "BBB"};
            projectionContainer2.Items.Add(projection2);

            Assert.AreEqual(2, projectionContainer2.Items.Count);
            projectionContainer2.RemoveItems(new List<object>() { projection1 });
            Assert.AreEqual(1, projectionContainer2.Items.Count);
        }

        #endregion RemoveItems

        #region AddTransitionInfoToDictionary

        [Test, RequiresSTA]
        public void AddTransitionInfoToDictionaryTest1()
        {
            var transitionInfo1 = new TransitionInfo()
                {
                    EventName = "MouseMove",
                    FromProjection = "AAA",
                    ToProjection = "BBB",
                    EventOwner = ""
                };
            var transitionInfo2 = new TransitionInfo()
            {
                EventName = "MouseMove",
                FromProjection = "DDD",
                ToProjection = "BBB",
                EventOwner = ""
            };
            var transitionInfo3 = new TransitionInfo()
            {
                EventName = "MouseDown",
                FromProjection = "DDD",
                ToProjection = "BBB",
                EventOwner = ""
            };
            var projectionContainer2 = new ProjectionContainerControl();
            var dictionary = new Dictionary<string, List<TransitionInfo>>();
            
            projectionContainer2.AddTransitionInfoToDictionary(dictionary, transitionInfo1);
            Assert.AreEqual(1, dictionary.Count);

            projectionContainer2.AddTransitionInfoToDictionary(dictionary, transitionInfo2);
            Assert.AreEqual(1, dictionary.Count);

            projectionContainer2.AddTransitionInfoToDictionary(dictionary, transitionInfo3);
            Assert.AreEqual(2, dictionary.Count);
        }

        #endregion

        #region GetEventOwner

        [Test, RequiresSTA]
        public void GetEventOwnerTest1()
        {
            var projectionContainer2 = new ProjectionContainerControl();
            var eventInfo = typeof(Button).GetEvent("Click");

            var eventOwner = projectionContainer2.GetEventOwner(eventInfo);
            Assert.AreEqual("ButtonBase", eventOwner);
        }

        [Test, RequiresSTA]
        public void GetEventOwnerTest2()
        {
            var projectionContainer2 = new ProjectionContainerControl();
            var eventInfo = typeof(ProjectionContainerControl).GetEvent("MouseMove");

            var eventOwner = projectionContainer2.GetEventOwner(eventInfo);
            Assert.AreEqual("", eventOwner);
        }

        #endregion GetEventOwner

        #endif
    }
}
